<?php
// +----------------------------------------------------------------------
// | Diygw PHP
// +----------------------------------------------------------------------
// | Copyright (c) 2022~2024 https://www.diygw.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: diygw <diygwcom@diygw.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);

namespace app\shop\controller;

use app\BaseController;
use app\shop\model\GoodsModel;
use app\shop\model\OrderModel;
use app\diy\model\UserModel;
use app\shop\model\SettingModel;
use EasyWeChat\Pay\Application;
use EasyWeChat\Pay\Message;
use think\App;

/**
 * @package app\shop\controller
 */
class OrderController extends BaseController
{
    //是否显示所有数据
    public $isAll = true;
    //是否初始化模型
    public $isModel = true;
    //判断是否全部不需要登录
    public $notNeedLoginAll = false;
    //判断不需要登录的方法
    public $notNeedLogin = ['notify'];

    /**
     * 用户下单
     * @return \think\response\Json
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \think\exception\DbException
     */
    public function order(){
        $userModel = UserModel::where(['id'=>$this->request->userId])->find();
        if(!$userModel){
            return $this->error('请先登录'.$this->request->userId);
        }
        $user = $userModel->toArray();
        if(empty($user['openid'])){
            return $this->error('请先登录');
        }
        $data = $this->request->param();

        //获取订单信息
        $model = new OrderModel();
        $data = $model->where('id',$data['id'])->find()->toArray();

        if($data['payStatus']=='1'){
           return $this->error("已支付，无需再次支付");
        }

        $notify_url = url('shop/order/notify')
            ->suffix('html')
            ->domain($this->request->domain())->build();

        //读取配置文件
        $paymentConfig = $this->getPaymentConfig();
        if(empty($paymentConfig['app_id'])){
            return $this->error('请先配置密钥');
        }
        $wepayApp =  new Application($paymentConfig);
        //调起微信支付
        $payData = [
            "mchid" => $paymentConfig['mch_id'],
            "out_trade_no" => getOrderNo(),
            "appid" => $paymentConfig['app_id'],
            "description" => $data['title'],
            "notify_url" => $notify_url, // 支付成功后回调通知URL
            "amount" => [
                "total" => (int)($data['total']*100),
                "currency" => "CNY",
            ],
            "payer" => [
                "openid" => $data['openid'],
            ],
        ];
        try {
            $response = $wepayApp->getClient()->postJson('v3/pay/transactions/jsapi', $payData);
            $result = $response->toArray(false);
            if (isset($result['prepay_id'])) {
                $utils = $wepayApp->getUtils();
                $config = $utils->buildMiniAppConfig($result['prepay_id'], $paymentConfig['app_id'], 'RSA'); // 返回数组
                return $this->successData($config);
            }else{
                if($this->isDebug){
                    $this->errorData($result,"发起支付失败");
                }else{
                    $this->error("发起支付失败");
                }
            }
        } catch (\Throwable $e) {
            return $this->error($e->getMessage());
        }

    }


    /**
     * 支付回调
     * @return mixed
     */
    public function notify(){

        $paymentConfig = $this->getPaymentConfig();
        if(empty($paymentConfig['app_id'])){
            return $this->error('请先配置密钥');
        }
        $wepayApp =  new Application($paymentConfig);
        $server = $wepayApp->getServer();
        $server->handlePaid(function (Message $message, \Closure $next) {
            // $message->out_trade_no 获取商户订单号
            // $message->payer['openid'] 获取支付者 openid
            $order = OrderModel::where(['order_no'=>$message->out_trade_no])->find();
            //如果状态已为1，直接返回
            if (!$order || $order['payStatus'] == '1') {
                return $next($message);
            }
            $order['pay_status'] = '1';
            $order['status'] = '1';
            $order->save();
            //修改产品数量
            $goodsModel = new GoodsModel();
            $goodsModel->changeByOrder($order);
            return $next($message);
        });
        return $server->serve();
    }

    private function getPaymentConfig(){
        $settingModel = new SettingModel();
        $setting = $settingModel->where('key','wechat')->find();
        if(empty($setting)){
            return [];
        }
        $settingData = $setting->toArray();
        if(empty($settingData['value'])){
            return [];
        }
        $settingValue= json_decode($settingData['value'],true);
        $rootPath = str_replace('\\', '/',  \config('filesystem.disks.local.root').DIRECTORY_SEPARATOR);
        $paymentConfig = [
            'app_id'    => $settingValue['appid'],
            'mch_id'    => $settingValue['pay_mch_id'],
            // v3 API 秘钥
            'secret_key'       => $settingValue['pay_signature'],
            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'certificate' => $rootPath.$settingValue['cert_path'], // XXX: 绝对路径！！！！
            'private_key'  => $rootPath.$settingValue['cert_key'],      // XXX: 绝对路径！！！！
        ];
        return $paymentConfig;
    }
}
